package com.atguigu.exam.service.impl;

import com.atguigu.exam.entity.AnswerRecord;
import com.atguigu.exam.entity.ExamRecord;
import com.atguigu.exam.entity.Paper;
import com.atguigu.exam.entity.Question;
import com.atguigu.exam.mapper.ExamRecordMapper;
import com.atguigu.exam.mapper.QuestionMapper;
import com.atguigu.exam.service.AnswerRecordService;
import com.atguigu.exam.service.ExamRecordService;
import com.atguigu.exam.service.ExamService;
import com.atguigu.exam.service.PaperService;
import com.atguigu.exam.vo.StartExamVo;
import com.atguigu.exam.vo.SubmitAnswerVo;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;

import java.time.LocalDateTime;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;


/**
 * 考试服务实现类
 */
@Service
@Slf4j
public class ExamServiceImpl extends ServiceImpl<ExamRecordMapper, ExamRecord> implements ExamService {

    @Autowired
    private ExamRecordService examRecordService;
    @Autowired
    private PaperService paperService;
    @Autowired
    private AnswerRecordService answerRecordService;
    @Autowired
    private QuestionMapper questionMapper;

    /**
     * 学生开始考试，创建考试记录并返回试卷内容
     * @param startExamVo
     * @return examRecord
     */
    @Override
    public ExamRecord startExam(StartExamVo startExamVo) {
        //1.校验 必须输入姓名
        if (ObjectUtils.isEmpty(startExamVo.getStudentName())){
            throw new RuntimeException("必须输入姓名");
        }
        //根据状态 {"进行中", "已完成", "已批阅"}检查该学生是否存在未完成的考试记录
        LambdaQueryWrapper<ExamRecord> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(ExamRecord::getExamId,startExamVo.getPaperId());
        lambdaQueryWrapper.eq(ExamRecord::getStudentName,startExamVo.getStudentName());
        lambdaQueryWrapper.eq(ExamRecord::getStatus,"进行中");
        ExamRecord examRecord = getOne(lambdaQueryWrapper);
        if (examRecord!=null){
            //存在未完成的考试记录，返回未完成的考试记录
            return examRecord;
        }
        //2.创建ExamRecord对象，进行部分赋值
        ExamRecord examRecord1 = new ExamRecord();
        examRecord1.setExamId(startExamVo.getPaperId());
        examRecord1.setStudentName(startExamVo.getStudentName());
        examRecord1.setStartTime(LocalDateTime.now());
        examRecord1.setStatus("进行中");
        examRecord1.setScore(0);
        //3.数据插入到数据库中
        save(examRecord1);
        //5.返回考试记录
        return examRecord1;
    }

    /**
     * 查询考试记录详情
     * @param id
     * @return examRecord
     */
    @Override
    public ExamRecord findExamRecordById(Integer id) {
        //返回一个聚合了试卷、题目、学生答案、得分、AI评语等所有信息的`ExamRecord`对象。
        //1.校验 考试记录是否存在 判断试卷是否存在
        ExamRecord examRecord = getById(id);
        if (examRecord == null) {
            throw new RuntimeException("考试记录不存在，已被删除");
        }
        Paper paper = paperService.getById(examRecord.getExamId());
        if (paper==null){
            throw new RuntimeException("试卷不存在，已被删除");
        }
        //2.加载试卷内容  @param 试卷id
        Paper paperDetailInfo = paperService.getPaperDetailInfo(paper.getId().intValue());
        examRecord.setPaper(paperDetailInfo);
        //3.获取考试记录对应的答题记录集合
        LambdaQueryWrapper<AnswerRecord> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(AnswerRecord::getExamRecordId,id);
        List<AnswerRecord> answerRecords = answerRecordService.list(lambdaQueryWrapper);
        if (!ObjectUtils.isEmpty(answerRecords)){
            //将试卷中的题目Id获取到 -> questionIdList
            List<Long> questionIdList = paperDetailInfo.getQuestions().stream().map(Question::getId).collect(Collectors.toList());
            //answer_record表中的question_id 按照 paper_question表中的question_id排序
            Comparator<AnswerRecord> c = new Comparator<AnswerRecord>() {
                @Override
                public int compare(AnswerRecord o1, AnswerRecord o2) {
                    return Integer.compare(questionIdList.indexOf(o1.getQuestionId()),questionIdList.indexOf(o2.getQuestionId()));
                }
            };
            answerRecords.sort(c);
        }
        examRecord.setAnswerRecords(answerRecords);
        return examRecord;
    }

    /**
     * 提交考试答案
     * @param examRecordId
     * @param answers
     */
    @Override
    public void submitAnswer(Integer examRecordId, List<SubmitAnswerVo> answers) {
        //1.校验 考生没有作答->提交 answers集合为空 不保存
        if (!ObjectUtils.isEmpty(answers)){
            //answers集合非空，保存答案记录 -> answer_record
            Function<SubmitAnswerVo,AnswerRecord> fun = new Function<SubmitAnswerVo, AnswerRecord>() {
                @Override
                public AnswerRecord apply(SubmitAnswerVo submitAnswerVo) {
                    AnswerRecord answerRecord = new AnswerRecord();
                    answerRecord.setExamRecordId(examRecordId);
                    answerRecord.setQuestionId(submitAnswerVo.getQuestionId());
                    answerRecord.setUserAnswer(submitAnswerVo.getUserAnswer());
                    return answerRecord;
                }
            };
            List<AnswerRecord> answerRecordList = answers.stream().map(fun).collect(Collectors.toList());
            //将答案集合进行批量插入
            answerRecordService.saveBatch(answerRecordList);
        }
        //2.【思考错误】将答题终止时间插入到 exam_records 表 end_time 中，以及修改试卷状态 status 为 “已完成”
        //应该是修改
        ExamRecord examRecord = examRecordService.getById(examRecordId);
        examRecord.setEndTime(LocalDateTime.now());
        examRecord.setStatus("已完成");
        examRecordService.updateById(examRecord);
        //3.调用判卷接口
        gradeExam(examRecordId);
    }

    /**
     * AI试卷批阅功能
     * @param examRecordId
     * @return examRecord
     */
    @Override
    public ExamRecord gradeExam(Integer examRecordId) {
        //1.获取考试记录 -> 试卷和答题记录
        ExamRecord examRecord = findExamRecordById(examRecordId);
        Paper paper = examRecord.getPaper();
        if (paper == null){
            examRecord.setStatus("已批阅");
            examRecord.setAnswers("考试对应的试卷被删除，无法进行成绩判定");
            updateById(examRecord);
            throw new RuntimeException("考试对应的试卷被删除，无法进行成绩判定");
        }
        //List<AnswerRecord> answerRecords = examRecord.getAnswerRecords();
        LambdaQueryWrapper<AnswerRecord> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(AnswerRecord::getExamRecordId,examRecordId);
        List<AnswerRecord> answerRecords = answerRecordService.list(lambdaQueryWrapper);
        if (ObjectUtils.isEmpty(answerRecords)){
            examRecord.setAnswers("考生没有进行作答，成绩为零");
            examRecord.setScore(0);
            examRecord.setStatus("已批阅");
            updateById(examRecord);
            return examRecord;
        }
        //2.进行循环判断，记录总分数，记录总正确数量，修改答题记录
        int correctNumber = 0;
        int totalScore = 0;
        //将试卷中的题目转成map
        Map<Long, Question> questionMap = paper.getQuestions().stream().collect(Collectors.toMap(Question::getId, q -> q));
        for (AnswerRecord answerRecord : answerRecords) {
            try {
                //1.先获取答题记录对应的题目对象
                Question question = questionMap.get(answerRecord.getQuestionId().longValue());
                String systemAnswer = question.getAnswer().getAnswer();
                String userAnswer = answerRecord.getUserAnswer();
                if ("JUDGE".equalsIgnoreCase(question.getType())){
                    userAnswer = normalizeJudgeAnswer(userAnswer);
                }
                if (!"TEXT".equals(question.getType())){
                    //判断题目类型,选择和判断直接判卷
                    if (systemAnswer.equalsIgnoreCase(userAnswer)){
                        answerRecord.setIsCorrect(1);
                        answerRecord.setScore(question.getPaperScore().intValue());     //在特定试卷中的分值
                    }else {
                        answerRecord.setIsCorrect(0);
                        answerRecord.setScore(0);
                    }
                }else{
                    //简答题

                }
            }catch (Exception e){
                answerRecord.setIsCorrect(0);
                answerRecord.setScore(0);
                answerRecord.setAiCorrection("判题过程出错");
            }
            //进行记录修改
            totalScore += answerRecord.getScore();
            if (answerRecord.getIsCorrect() == 1){
                correctNumber++;
            }
            //更新答案记录表
            answerRecordService.updateById(answerRecord);
        }
        //3.进行AI生成评价，进行考试记录修改和完善
        examRecord.setScore(totalScore);
        examRecord.setAnswers("暂时没有调用AI");
        examRecord.setStatus("已批阅");
        examRecordService.updateById(examRecord);
        return examRecord;
    }

    private String normalizeJudgeAnswer(String answer){
        if (answer == null || answer.trim().isEmpty()){
            return "";
        }
        String normalized = answer.trim().toUpperCase();
        switch (normalized){
            case "T":
            case "TRUE":
            case "正确":
                return "TRUE";
            case "F":
            case "FALSE":
            case "错":
                return "FALSE";
            default:
                return normalized;
        }
    }
}